package cn.easy.service.impl;

import cn.easy.api.TriggerService;
import cn.easy.common.pojo.SensorType;
import cn.easy.common.pojo.TriggerCondtion;
import cn.easy.mapper.*;
import cn.easy.pojo.*;
import cn.easy.vo.TriggerInfoVo;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;

import javax.annotation.PostConstruct;
import java.util.List;

@Service
public class TriggerServiceImpl implements TriggerService {
    @Autowired
    private UserMapper userMapper;
    @Autowired

    private ActionMapper actionMapper;
    @Autowired
    private SensorMapper sensorMapper;
    @Autowired
    private EasytriggerMapper triggerMapper;
    @Autowired
    private DeviceMapper deviceMapper;


    @Override
    public void insertTrigger(Easytrigger trigger, String userKey) throws Exception {
        User user = userMapper.selectByUserKey(userKey);
        if (user == null) throw new Exception("找不到此用户");
        //拿到新增操作的传感器类型
        Integer sensorId = trigger.getSensorId();
        Sensor sensor = sensorMapper.selectByPrimaryKey(sensorId);
        if (sensor == null) throw new Exception("传感器不存在");
        Integer sensorType = sensor.getSensorType();

        Device device = deviceMapper.selectByPrimaryKey(sensor.getDeviceId());
        if (device == null) throw new Exception("找不到传感器对应的设备");
        if (device.getUserId() != user.getUserId()) throw new Exception("用户身份验证失败");

        /*--------------对不同类型的触发器，要做不同的处理,设置判断符号和临界数这两项------------*/
        trigger = checkTriggerConditionNumber(trigger, sensorType);
        /*--------------触发器规则检测完毕，执行新增操作------------*/
        triggerMapper.insert(trigger);
    }

    /**
     * 删除一个触发器
     *
     * @param triggerId
     * @param userKey
     * @throws Exception
     */
    @Override
    public void deleteTrigger(int triggerId, String userKey) throws Exception {
        /*--------------找到触发器------------*/
        Easytrigger trigger = triggerMapper.selectByPrimaryKey(triggerId);
        if (trigger == null) throw new Exception("找不到触发器");
        /*--------------删除触发器------------*/
        //身份验证
        Integer sensorId = trigger.getSensorId();
        Sensor sensor = sensorMapper.selectByPrimaryKey(sensorId);
        if (sensor == null) throw new Exception("找不到对应的传感器");
        Device device = deviceMapper.selectByPrimaryKey(sensor.getDeviceId());
        if (device == null) throw new Exception("找不到对应的设备");
        User user = userMapper.selectByPrimaryKey(device.getUserId());
        if (user == null) throw new Exception("找不到对应的用户");
        //取出用户的key
        if (!userKey.equals(user.getUserKey())) throw new Exception("身份验证失败");
        triggerMapper.deleteByPrimaryKey(triggerId);
    }

    /**
     * 更新一个触发器
     *
     * @param trigger
     * @param userKey
     * @throws Exception
     */
    @Override
    public void updateTrigger(Easytrigger trigger, String userKey) throws Exception {
        /*--------------必要参数检查------------*/
        if (trigger.getTriggerId() == null) throw new Exception("触发器主键缺失");
        /*--------------获取 旧的触发器,并完成数据组装------------*/
        Easytrigger old = triggerMapper.selectByPrimaryKey(trigger.getTriggerId());

        //穿插执行身份验证
        User user = userMapper.selectByUserKey(userKey);
        if (user == null) throw new Exception("找不到用户");
        Sensor sensor = sensorMapper.selectByPrimaryKey(trigger.getSensorId());
        if (sensor == null) throw new Exception("找不到对应的传感器");
        Device device = deviceMapper.selectByPrimaryKey(sensor.getDeviceId());
        if (device == null) throw new Exception("找不到对应的设备");
        if (device.getUserId() != user.getUserId()) throw new Exception("身份验证失败");


        if (trigger.getTriggerCondition() != null) trigger.setTriggerCondition(trigger.getTriggerCondition());
        if (trigger.getTriggerNumber() != null) trigger.setTriggerNumber(trigger.getTriggerNumber());
        if (trigger.getActionId() != null) trigger.setActionId(trigger.getActionId());
        /*--------------完成update操作------------*/
        triggerMapper.updateByPrimaryKey(trigger);
    }

    /**
     * 获取一个传感器下所有的触发器
     *
     * @param sensorId
     * @param userKey
     * @return
     * @throws Exception
     */
    @Override
    public List<Easytrigger> searchSensorAllTrigger(Integer sensorId, String userKey) throws Exception {
        Sensor sensor = sensorMapper.selectByPrimaryKey(sensorId);
        if (sensor == null) throw new Exception("找不到对应的传感器");
        Device device = deviceMapper.selectByPrimaryKey(sensor.getDeviceId());
        if (device == null) throw new Exception("找不到对应的设备");
        User user = userMapper.selectByPrimaryKey(device.getUserId());
        if (user == null) throw new Exception("找不到对应的用户");
        if (!user.getUserKey().equals(userKey)) throw new Exception("身份验证失败");
        EasytriggerExample example = new EasytriggerExample();
        EasytriggerExample.Criteria criteria = example.createCriteria();
        criteria.andSensorIdEqualTo(sensorId);
        List<Easytrigger> list = triggerMapper.selectByExample(example);
        return list;
    }

    @Override
    public List<TriggerInfoVo> getSensorAllTriggers(Integer sensorId, String userKey) throws Exception {
        /*step1 权限判断*/
        checkUser(sensorId, userKey);
        /*step2 获取传感器下所有的触发器*/
        List<TriggerInfoVo> triggerList = triggerMapper.getSensorAllTriggers(sensorId);
        return triggerList;
    }

    @Override
    public Easytrigger getTriggerInfo(Integer id, String userKey) throws Exception {
        //找到触发器所属的传感器
        Easytrigger easytrigger = triggerMapper.selectByPrimaryKey(id);
        Integer sensorId = easytrigger.getSensorId();
        //权限判断
        checkUser(sensorId, userKey);
        return easytrigger;
    }


    private void checkUser(Integer sensorId, String userKey) throws Exception {
        Integer deviceId;
        Integer userId;
        /*step1 判断传感器是否公开，如果没有公开先进行身份验证*/
        Sensor sensor = sensorMapper.selectByPrimaryKey(sensorId);
        //1.1 寻找传感器
        if (sensor == null) {
            throw new Exception("找不到传感器");
        }
        deviceId = sensor.getDeviceId();

        //1.2 寻找设备
        Device device = deviceMapper.selectByPrimaryKey(deviceId);
        if (device == null) {
            throw new Exception("找不到设备");
        }
        userId = device.getUserId();
        //1.3 寻找用户
        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null) {
            throw new Exception("找不到用户");
        }
        //1.4 判断是不是私有设别，是的话身份验证
        if (device.getDevicePersonal() == 0) {
            if (!userKey.equals(user.getUserKey())) {
                throw new Exception("访问私有设备身份验证失败");
            }
        }
    }

    public static Easytrigger checkTriggerConditionNumber(Easytrigger trigger, Integer sensorType) throws Exception {
        boolean flag = true;
        //开关
        if (sensorType == SensorType.SWITCH.getIndex()) {
            /*开关，那么就两种状态 开关
            所以触发条件就是 number=1(打开) number=0(关闭)两种情况
            所以condition其实就不用看了直接就是等于*/

            trigger.setTriggerCondition(TriggerCondtion.EQUAL.getIndex());//比较符 等于

            //判断数据number是不是1/0
            String triggerNumber = trigger.getTriggerNumber();
            if (triggerNumber.equals("1") || triggerNumber.equals("0")) trigger.setTriggerNumber(triggerNumber);
            else throw new Exception("未知的开关状态");
        }
        //数值
        if (sensorType == SensorType.NUMBER.getIndex()) {
            trigger.setTriggerCondition(trigger.getTriggerCondition());//比较符号
            //判断是不是数字
            try {
                Float.parseFloat(trigger.getTriggerNumber());
            } catch (Exception e) {
                throw new Exception("数值型传感器的临界值必须为数字");
            }
            trigger.setTriggerNumber(trigger.getTriggerNumber());
        }
        //GPS
        //TODO ： GPS 传感器数据验证未实现

        if (sensorType == SensorType.GPS.getIndex()) {
            //gps 按照  经度#纬度#半径 作为传输值和临界值
            //比较符 只能为> 或者<=
            //这里把 > >= 等价成 >,< = <= 等价成<
            String tr = trigger.getTriggerNumber();
        }
        return trigger;
    }

}
